﻿namespace Pub.Class
{
    using System;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Timers;

    public class Timer
    {
        private int degree;
        private bool end;
        public System.Action exec;
        private string hhmm;
        private long index;
        private int initInterval;
        private System.Timers.Timer timer;
        private bool useThread;

        public Timer()
        {
            this.hhmm = string.Empty;
            this.useThread = false;
        }

        public Timer(bool useThread)
        {
            this.hhmm = string.Empty;
            this.useThread = useThread;
        }

        public void Start(int degree = 0)
        {
            if (this.initInterval > 0)
            {
                this.Start(this.exec, this.initInterval, degree);
            }
            if (!this.hhmm.IsNullEmpty())
            {
                this.Start(this.exec, this.hhmm, degree);
            }
        }

        public void Start(System.Action action, int degree = 0)
        {
            this.Start(action, 1, degree);
        }

        public void Start(System.Action action, int interval = 1, int degree = 0)
        {
            this.Stop();
            if (interval < 1)
            {
                interval = 1;
            }
            this.degree = degree;
            if (this.timer.IsNull())
            {
                this.exec = action;
                this.timer = new System.Timers.Timer((double) (interval * 0x3e8));
                this.timer.Elapsed += new ElapsedEventHandler(this.timer_Elapsed);
                this.timer.Enabled = true;
                this.timer.Start();
            }
        }

        public void Start(System.Action action, string HHmm, int degree = 0)
        {
            this.Stop();
            this.degree = degree;
            if (this.timer.IsNull())
            {
                this.exec = action;
                this.hhmm = HHmm;
                this.timer = new System.Timers.Timer(60000.0);
                this.timer.Elapsed += new ElapsedEventHandler(this.timer2_Elapsed);
                this.timer.Enabled = true;
                this.timer.Start();
            }
        }

        public void Stop()
        {
            if (this.timer.IsNotNull())
            {
                this.timer.Stop();
                this.timer.Dispose();
                this.timer = null;
            }
        }

        protected void timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            ThreadStart start = null;
            if (!this.exec.IsNull() || !this.end)
            {
                if (this.useThread)
                {
                    if (start == null)
                    {
                        start = () => this.exec();
                    }
                    new Thread(start).Start();
                }
                else
                {
                    this.exec();
                }
                if ((this.degree > 0) && !this.end)
                {
                    this.index += 1L;
                }
                if ((this.degree > 0) && (this.degree <= this.index))
                {
                    this.end = true;
                    this.Stop();
                }
            }
        }

        protected void timer2_Elapsed(object sender, ElapsedEventArgs e)
        {
            ThreadStart start = null;
            if ((!this.exec.IsNull() || !this.end) && (DateTime.Now.ToString("HH:mm") == this.hhmm))
            {
                if (this.useThread)
                {
                    if (start == null)
                    {
                        start = () => this.exec();
                    }
                    new Thread(start).Start();
                }
                else
                {
                    this.exec();
                }
                if ((this.degree > 0) && !this.end)
                {
                    this.index += 1L;
                }
                if ((this.degree > 0) && (this.degree <= this.index))
                {
                    this.end = true;
                    this.Stop();
                }
            }
        }

        public System.Action Action
        {
            get
            {
                return this.exec;
            }
            set
            {
                this.exec = value;
            }
        }

        public bool End
        {
            get
            {
                return this.end;
            }
        }

        public string HHmm
        {
            get
            {
                return this.hhmm;
            }
            set
            {
                this.hhmm = value;
                this.initInterval = 0;
            }
        }

        public int Interval
        {
            get
            {
                return this.initInterval;
            }
            set
            {
                this.initInterval = value;
                this.hhmm = string.Empty;
            }
        }
    }
}

